package com.websocket;

import com.protos.Peer;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Vector;

/**
 * ws订阅事件({@code RepChain Event})
 * @author zyf
 */
public class wsSyncClient extends WebSocketClient implements ObservableEvent {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 观察者列表
     */
    private Vector<Observer> list;

    /**
     * 订阅到的Event
     */
    private Peer.Event event;

    public wsSyncClient(URI serverURI) {
        super(serverURI);
    }

    public wsSyncClient(String host) {
        super(URI.create("ws://" + host + "/event"));
    }

    @Override
    public void onOpen(ServerHandshake handShakeData) {
        logger.info("opened connection");
    }

    @Override
    public void onClose(int code, String reason, boolean remote ) {
        logger.info( "Connection closed by " + ( remote ? "remote peer" : "us" ) + " Code: " + code + " Reason: " + reason );
    }

    @Override
    public void onMessage(String message) {
        System.out.println("received message: " + message);
    }

    /**
     *
     * @param message
     */
    @Override
    public void onMessage(ByteBuffer message) {
        try {
            byte[] bytes = new byte[message.capacity()];
            message.get(bytes, 0, bytes.length);
            Peer.Event event = Peer.Event.parseFrom(bytes);
            if (event.hasBlk()) {
                if (list != null && !list.isEmpty()) {
                    notifyObserver(event);
                }
//                this.event = event;
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
    }

    @Override
    public void onError(Exception ex) {
        logger.error("an error occurred: {}", ex.getMessage(), ex);
    }


    /**
     *
     * @param list  观察者列表
     */
    public void setList(Vector<Observer> list) {
        this.list = list;
    }

    /**
     * 创建观察者列表
     */
    public void createObserverList() {
        this.list = new Vector<>();
    }

    /**
     * 注册观察者到列表中
     * @param o 观察者
     */
    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }

    /**
     * 从列表中移除某个观察者
     * @param o 观察者
     */
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty()) {
            list.remove(o);
        }
    }

    /**
     * 遍历用户给用户推送新消息
     * @param event
     */
    @Override
    public void notifyObserver(Peer.Event event) {
        for(int i = 0; i < list.size(); i++) {
            Observer observer = list.get(i);
            observer.notify(event);
        }
    }

}

